/*************************************************************************
Program Name: gradeana.cpp
Des: This program will input student grades and allow a user to obtain the
mean of the grades, mean with high and low grades dropped and grade ranges.
This program enlists the help of the List class to code the solution.
Author: Alberto De Pena
Due Date: 10/14/09 @ 11:55pm
*************************************************************************/

#include <iostream>

//contains List class definition which will be needed to provide a solution
#include "List.h"

using namespace std;

/*************************************************************************
GLOBAL DECLARATIONS
*************************************************************************/

const int EXIT = '4';

//Instantiate the List object
List Grades;

/*************************************************************************
Function Name: MenuPrompt
Des: This function is responsible for displaying the menu to the screen
	  showing the user the options available for use.  The function will
	  also obtain the option and send it back for later use.
*************************************************************************/

void MenuPrompt (char &Opt)
{
	 cout << "What do you wish to do? "<< endl << endl;
	 cout << "ENTER 1 to obtain the mean " << endl;
	 cout << "ENTER 2 to obtain the mean with high and low grades dropped "
			<< endl;
	 cout << "ENTER 3 to obtain the count of A's, B's, C's, D's and F's "
			<< endl;
	 cout << "ENTER 4 to EXIT the program "<< endl << endl;
	 cout << "? ";
	 cin >> Opt;
}

/*************************************************************************
Function Name: PrintMean
Des: This function will print out the mean of the grades.  It will call
	  the method "ListMean" found in the List class.
*************************************************************************/

void PrintMean ()
{
	cout.setf (ios::fixed,ios::floatfield);
	cout.setf (ios::showpoint);
	cout.precision(2);
  	cout << "The mean of the grades entered is "
	     << Grades.ListMean() << endl << endl;
}

/*************************************************************************
Function Name: PrintHLmean
Des: This function will drop the high and low grades found in the List of
	  Grades to find an average.  It will use the methods "ListHigh",
     "ListLow", "ListSum" and "ListCount" found in the List class.
*************************************************************************/

void PrintHLmean ()
{
	ListType HLmean;

	if (Grades.ListCount() > 2)
	{
	     HLmean = (Grades.ListSum() - (Grades.ListHigh() + Grades.ListLow()))
					 / (Grades.ListCount() - 2);
         cout.setf (ios::fixed,ios::floatfield);
		 cout.setf (ios::showpoint);
		 cout.precision(2);
		 cout << "The mean of the grades entered with the high and low ";
		 cout << "grade dropped is " << HLmean << endl;
		 cout << endl;
	}
	else
		 cout << "You must have more than 2 grades to get this type "
				<< "of mean. " << endl << endl;
}

/*************************************************************************
Function Name: PrintGradeCount
Des:  This function will print the number of A's, B's, C's, D's, and F's
		found in the List of Grades.  Pre-defined constants are used for
		the ranges found within each letter grade.  It will use the method
		"ListRange" found in the List class.
*************************************************************************/

void PrintGradeCount ()
{
	const ListType HIGH_A = 100;
	const ListType LOW_A = 90;
	const ListType HIGH_B = 89.999;
	const ListType LOW_B = 80;
	const ListType HIGH_C = 79.999;
	const ListType LOW_C = 70;
	const ListType HIGH_D = 69.999;
	const ListType LOW_D = 60;
	const ListType HIGH_F = 59.999;

  	cout << endl << endl;
	cout << "A's: " << Grades.ListRange(HIGH_A,LOW_A) << endl;
	cout << "B's: " << Grades.ListRange(HIGH_B,LOW_B) << endl;
	cout << "C's: " << Grades.ListRange(HIGH_C,LOW_C) << endl;
	cout << "D's: " << Grades.ListRange(HIGH_D,LOW_D) << endl;
	cout << "F's: " << Grades.ListRange(HIGH_F,0) << endl << endl;
}

/*************************************************************************
Function Name: Execute
Des:  This function will drive the execution of the menu options.
Parameters: opt - contains the menu option obtained in MenuPrompt.
*************************************************************************/

void Execute (char Opt)
{
	 switch (Opt)
	 {
		  case '1':
			PrintMean();
			break;

		  case '2':
			if (Grades.ListCount() > 2)
				PrintHLmean();
			else
				cout << "There must be more than 2 grades to get this average."
					  << endl;
			break;

		  case '3':
			 PrintGradeCount();
			 break;

		  case '4':
			 cout << "PROGRAM TERMINATED" << endl;
			 break;

		  default:
			 cout << "INVALID OPTION ... TRY AGAIN " << endl;
	}
}

/*************************************************************************
Function Name: GetGrades
Des:  This function will obtain grades from the keyboard and add them
		to the Grades object by using the method ListAdd.  Grades entered
		must be terminated by a -1 to signal no more grades.
*************************************************************************/

void GetGrades ()
{
   const int LOWGRADE = 0;
   const int HIGHGRADE = 100;
   ListType Grade;

   cout << "Enter grade (-1 to terminate input): ";
   cin >> Grade;
   while (Grade != -1)
   	if (Grade < LOWGRADE || Grade > HIGHGRADE)
      {
      	cout << "Grade out of range...re-enter grade please: ";
         cin >> Grade;
      }
      else
      	if (!Grades.ListAdd(Grade))
         {
         	cout << Grade << " not entered...grade list is full" << endl;
            Grade = -1;
         }
         else
         {
         	cout << "Enter grade (-1 to terminate input): ";
         	cin >> Grade;
         }
}

/*************************************************************************
MAIN PROGRAM
*************************************************************************/

void main()
{
	char Option;

	GetGrades();
	if (Grades.ListCount() > 0)
	 do
	 {
	  MenuPrompt (Option);
	  Execute (Option);
	 }
	 while (Option != EXIT);
}